001 /** 002 * Created by IntelliJ IDEA. 003 * User: Wei Wang 004 * Date: Mar 2, 2003 005 * Time: 9:05:11 PM 006 */ 007 008 package EVolve.visualization; 009 010 import javax.swing.*; 011 import java.awt.*; 012 import java.awt.event.MouseAdapter; 013 import java.awt.event.MouseEvent; 014 import java.awt.event.MouseMotionAdapter; 015 import java.awt.image.BufferedImage; 016 import java.awt.geom.AffineTransform; 017 import java.awt.geom.Point2D; 018 import java.awt.geom.Rectangle2D; 019 import java.util.ArrayList; 020 021 public class AxesPanel extends JPanel{ 022 public final static int Axis_Enabled = 0x00001; 023 public final static int Scale_Image = 0x00010; 024 public final static int Flip_Image = 0x00100; 025 public final static int Pointer_Enabled = 0x01000; 026 public final static int Box_Enabled = 0x10000; 027 public final static int Null = 0x0; 028 029 private int flag; 030 private String xName=" ", yName=" "; 031 private Point origin, imageAdjustment, pointerPosition; 032 private Point boxStart, boxEnd; 033 private Point2D.Double mousePos; 034 private int zoomingWidth, zoomingHeight, shapeSize; 035 private BufferedImage image; 036 private JScrollPane parent = null; 037 private ArrayList phases; 038 039 public AxesPanel(int flag) { 040 this.flag = flag; 041 origin = new Point(0,0); 042 imageAdjustment = new Point(0,0); 043 pointerPosition = new Point(0,0); 044 boxStart = new Point(0,0); 045 boxEnd = new Point(0,0); 046 mousePos = new Point2D.Double(0,0); 047 zoomingWidth = zoomingHeight = 20; 048 shapeSize = 1; 049 if ((flag & 0x000f) == Axis_Enabled) { 050 origin.setLocation(20,20); 051 imageAdjustment.x = 60; 052 imageAdjustment.y = 60; 053 } 054 addMouseListener(new MouseAdapter() { 055 public void mousePressed(MouseEvent e) { 056 if (e.getButton() == MouseEvent.BUTTON1) { 057 mPressed(e.getX(), e.getY()); 058 } 059 } 060 }); 061 062 addMouseListener(new MouseAdapter() { 063 public void mouseReleased(MouseEvent e) { 064 if (e.getButton() == MouseEvent.BUTTON1) { 065 mReleased(); 066 } 067 } 068 }); 069 070 addMouseMotionListener(new MouseMotionAdapter() { 071 public void mouseDragged(MouseEvent e) { 072 mDragged(e.getX(), e.getY()); 073 } 074 }); 075 } 076 077 private void drawAxis(Graphics2D g2) { 078 079 if ((flag & 0x000f)==Axis_Enabled) {//axis is enabled 080 int w = getWidth(), h = getHeight(); 081 g2.setColor(Color.black); 082 g2.drawLine(origin.x, h - origin.y, w - origin.x, h - origin.x); 083 g2.drawLine(w - origin.x, h - origin.y, w - 30, h - 15); 084 g2.drawLine(w - origin.x, h - origin.y, w - 30, h - 25); 085 g2.drawLine(origin.x, h - origin.y, origin.x, origin.y); 086 g2.drawLine(origin.x, origin.y, 15, 30); 087 g2.drawLine(origin.x, origin.y, 25, 30); 088 089 090 Font font = new Font("Arial", Font.PLAIN, 12); 091 g2.setFont(font); 092 g2.drawString(xName, w - g2.getFontMetrics().stringWidth(xName) - 40, h - 5); 093 g2.rotate(-Math.PI / 2.0); 094 g2.drawString(yName, -40 - g2.getFontMetrics().stringWidth(yName), 15); 095 g2.rotate(Math.PI / 2.0); 096 } 097 } 098 099 private void drawImage(Graphics2D g2) { 100 int w = getWidth(), h = getHeight(), flip = 1; 101 AffineTransform tf = g2.getTransform(); 102 103 if ((flag&0x0f00)==Flip_Image) { 104 flip = -1; 105 g2.translate(origin.x+1, h - origin.y); 106 } 107 108 if ((flag&0x00f0)==Scale_Image) { 109 g2.scale((double)(w - imageAdjustment.x) / (double)(image.getWidth()), 110 (double)flip * (double)(h - imageAdjustment.y) / (double)(image.getHeight())); 111 g2.drawImage(image, 0, 0, null); 112 } else { 113 if ((flag&0x0000f) == Axis_Enabled) { 114 g2.scale(1,flip); 115 } 116 g2.drawImage(image, 0, 0, null); 117 } 118 g2.setTransform(tf); 119 } 120 121 private void drawBox(Graphics2D g2) { 122 g2.setColor(Color.blue); 123 int x1 = (boxStart.x < boxEnd.x) ? boxStart.x : boxEnd.x; 124 int x2 = (boxStart.x > boxEnd.x) ? boxStart.x : boxEnd.x; 125 int y1 = (boxStart.y < boxEnd.y) ? boxStart.y : boxEnd.y; 126 int y2 = (boxStart.y > boxEnd.y) ? boxStart.y : boxEnd.y; 127 g2.drawRect(x1, y1, x2 - x1, y2 - y1); 128 } 129 130 private void drawPhases(Graphics2D g2) { 131 double xFactor = 1; 132 int w = getWidth(), h = getHeight(); 133 134 if (phases == null) return; 135 136 if ((flag&0x00f0)==Scale_Image) { 137 xFactor = (double)(w - imageAdjustment.x) / (double)(image.getWidth()); 138 } 139 140 g2.setColor(Color.black); 141 for (int i=0; i<phases.size(); i++) { 142 int phaseEnd = ((Integer)phases.get(i)).intValue(); 143 144 if (phaseEnd <= 0) continue; 145 146 g2.drawString(String.valueOf(phaseEnd),(int)(phaseEnd*xFactor)+origin.x,10); 147 g2.drawLine((int)(phaseEnd*xFactor)+origin.x, h-origin.y, (int)(phaseEnd*xFactor)+origin.x, origin.y); 148 } 149 150 } 151 152 private void drawPointer(Graphics2D g2) { 153 if ((flag&0xf000)==Pointer_Enabled) { 154 int x = pointerPosition.x, y = pointerPosition.y; 155 g2.setColor(Color.black); 156 g2.drawLine(x,y,x+20,y+20); 157 g2.drawLine(x,y,x+10,y+5); 158 g2.drawLine(x,y,x+5,y+10); 159 } 160 } 161 162 private void setPreferredPanelSize() { 163 if (parent == null) return; 164 165 if ((flag&0x000f0) != Scale_Image) { 166 setPreferredSize(new java.awt.Dimension(image.getWidth()+imageAdjustment.x,image.getHeight()+imageAdjustment.y)); 167 } else { 168 setPreferredSize(new java.awt.Dimension(parent.getWidth()-14, parent.getHeight()-14)); 169 } 170 revalidate(); 171 } 172 173 public void paintComponent(Graphics g) { 174 super.paintComponent(g); 175 176 Graphics2D g2 = (Graphics2D)g; 177 178 int w = getWidth(); 179 int h = getHeight(); 180 181 g2.setColor(Color.white); 182 g2.fillRect(0, 0, w, h); 183 184 drawAxis(g2); 185 186 if (image != null) { 187 setPreferredPanelSize(); 188 drawImage(g2); 189 drawBox(g2); 190 drawPhases(g2); 191 } 192 drawPointer(g2); 193 194 } 195 196 protected void mPressed(int x, int y) { 197 if (image != null) { 198 boxStart.x = x; 199 boxStart.y = y; 200 boxEnd.x = x; 201 boxEnd.y = y; 202 flag = flag | Box_Enabled; 203 repaint(); 204 } 205 } 206 207 protected void mReleased() { 208 if (image != null) { 209 flag = flag & 0x0ffff; 210 } 211 } 212 213 protected void mDragged(int x, int y) { 214 if ((image != null)&&((flag &0xf0000) == Box_Enabled)) { 215 boxEnd.x = x; 216 boxEnd.y = y; 217 repaint(); 218 } 219 } 220 221 public void setName(String xName, String yName) { 222 this.xName = xName; 223 this.yName = yName; 224 } 225 226 public void setImage(BufferedImage image) { 227 this.image = image; 228 229 boxStart.x = 0; 230 boxStart.y = 0; 231 boxEnd.x = 0; 232 boxEnd.y = 0; 233 flag = flag & 0x0ffff; 234 } 235 236 public int getImageX(int x) { 237 if (image == null) return -1; 238 239 if ((flag & 0x000f0) == Scale_Image) 240 return (int)((float)(x-origin.x)*((float)image.getWidth()/(float)(getWidth()-imageAdjustment.x))); 241 else 242 return x - origin.x; 243 } 244 245 public int getImageY(int y) { 246 if (image == null) return -1; 247 248 if ((flag & 0x000f0) == Scale_Image) { 249 if ((flag & 0x00f00) == Flip_Image) 250 return (int)((float)(getHeight()-origin.y-y)*((float)image.getHeight()/(float)(getHeight()-imageAdjustment.y))); 251 else 252 return (int)((float)(y-origin.y)*((float)image.getHeight()/(float)(getHeight()-imageAdjustment.y))); 253 } 254 else { 255 if ((flag & 0x00f00) == Flip_Image) 256 return getHeight()-origin.y-y; 257 else 258 return y - origin.y; 259 } 260 } 261 262 public int getStartX() { 263 int x = (boxStart.x < boxEnd.x) ? boxStart.x : boxEnd.x; 264 return getImageX(x); 265 } 266 267 public int getEndX() { 268 int x = (boxStart.x > boxEnd.x) ? boxStart.x : boxEnd.x; 269 return getImageX(x); 270 } 271 272 public int getStartY() { 273 int y = (boxStart.y < boxEnd.y) ? boxStart.y : boxEnd.y; 274 return getImageY(y); 275 } 276 277 public int getEndY() { 278 int y = (boxStart.y > boxEnd.y) ? boxStart.y : boxEnd.y; 279 return getImageY(y); 280 } 281 282 public void setPointerPosition(int x, int y) { 283 pointerPosition.x = x; 284 pointerPosition.y = y; 285 } 286 287 public void enablePointer(boolean draw) { 288 if (draw) 289 flag = flag | Pointer_Enabled; 290 else 291 flag = flag & (~Pointer_Enabled); 292 } 293 294 private Rectangle2D.Double calcZoomingArea(int x, int y) { 295 int w = image.getWidth(), h = image.getHeight(); 296 297 double x1=x,y1=y,w1,h1; 298 299 x1 = x1 - (double)zoomingWidth*shapeSize/2; 300 y1 = y1 - (double)zoomingHeight*shapeSize/2; 301 302 w1 = zoomingWidth*shapeSize; 303 h1 = zoomingHeight*shapeSize; 304 305 mousePos.setLocation(shapeSize*zoomingWidth/2,shapeSize*zoomingHeight/2); 306 if (x1 < 0) { 307 mousePos.x+=x1; 308 w1 = w1+x1; 309 x1 = 0; 310 } 311 if (x1 + w1 > w) { 312 w1 = w - x1; 313 } 314 315 if (y1 < 0) { 316 mousePos.y+=y1; 317 h1 = h1+y1; 318 y1 = 0; 319 } 320 if (y1 + h1 > h) { 321 h1 = h - y1; 322 } 323 324 Rectangle2D.Double ret = new Rectangle2D.Double(); 325 ret.x = x1; 326 ret.y = y1; 327 ret.width = w1; 328 ret.height = h1; 329 return ret; 330 } 331 332 public BufferedImage getSubImage(int x, int y) { 333 int w = image.getWidth(), h = image.getHeight(); 334 Rectangle2D.Double zooming = calcZoomingArea(x,y); 335 336 if ((image == null)||(zooming.x>w)||(zooming.y>h)) 337 return null; 338 339 if ((zooming.width<=0) || (zooming.height<=0)) return null; 340 341 return image.getSubimage((int)zooming.x,(int)zooming.y,(int)zooming.width,(int)zooming.height); 342 } 343 344 public void drawZoomingArea(int x, int y) { 345 double coX = 1, coY = 1; 346 347 if ((flag & 0x00f0) == Scale_Image) { 348 coX = (double)(getWidth() - imageAdjustment.x)/(double)image.getWidth(); 349 coY = (double)(getHeight() - imageAdjustment.y)/(double)image.getHeight(); 350 } 351 int deltaX = (int)(coX*zoomingWidth*shapeSize/2); 352 int deltaY = (int)(coY*zoomingHeight*shapeSize/2); 353 354 boxStart.x = x - deltaX; 355 boxStart.y = y - deltaY; 356 boxEnd.x = x + deltaX; 357 boxEnd.y = y + deltaY; 358 flag = flag | Box_Enabled; 359 repaint(); 360 flag = flag & (~Box_Enabled); 361 } 362 363 public void setShapeSize(int shapeSize) { 364 this.shapeSize = shapeSize; 365 } 366 367 public void setZoomingSize(int w, int h) { 368 zoomingWidth = w; 369 zoomingHeight = h; 370 } 371 372 public Point2D.Double getMouseMovement() { 373 return mousePos; 374 } 375 376 public void scaleImage(boolean scaled) { 377 if (scaled) 378 flag = flag | Scale_Image; 379 else 380 flag = flag & (~Scale_Image); 381 } 382 383 public void setParent(JScrollPane parent) { 384 this.parent = parent; 385 } 386 387 public void setPanelFlag(int flag) { 388 this.flag = flag; 389 if ((flag & 0x000f) != Axis_Enabled) { 390 origin.setLocation(0,0); 391 imageAdjustment.x = 0; 392 imageAdjustment.y = 0; 393 } 394 } 395 396 public Point getOrigin() { 397 return origin; 398 } 399 400 public void setPhases(ArrayList phases) { 401 this.phases = phases; 402 } 403 404 public Object clone() { 405 AxesPanel o = new AxesPanel(flag); 406 407 o.xName = xName; 408 o.yName = yName; 409 o.zoomingWidth = zoomingWidth; 410 o.zoomingHeight = zoomingHeight; 411 o.shapeSize = shapeSize; 412 return o; 413 } 414 }